#pragma once

enum {
	SessionHandleForward = 100,
};

#define GC_DELAY_TIME (3)
#define INST_UID_INVALID (u32(-1))

extern const ObjGUID ObjGUID_NULL;
extern const InstGUID InstGUID_NULL;
extern const int objTypeFlags[];
extern const int objValuesCount[];
extern const int obj64ValuesCount[];

#define IS_TYPE(tSrcType,tDesType) ((tSrcType)==(tDesType))
#define IS_KIND_OF(tSrcType,tDesType) \
	((objTypeFlags[tSrcType]&objTypeFlags[tDesType])==objTypeFlags[tDesType])

inline ObjGUID GetGuidFromValue(uint64 objGUID) {
	ObjGUID objGuid;
	objGuid.objGUID = objGUID;
	return objGuid;
}
inline ObjGUID GetGuidFromValue(uint16 SID, uint64 objGUID) {
	ObjGUID objGuid;
	objGuid.objGUID = objGUID;
	objGuid.SID = SID;
	return objGuid;
}
inline ObjGUID GetGuidFromLowGuid(uint16 TID, uint32 UID) {
	ObjGUID objGuid;
	objGuid.SID = 0;
	objGuid.TID = TID;
	objGuid.UID = UID;
	return objGuid;
}
inline ObjGUID GetGuidFromLowGuid4Player(uint32 UID) {
	return GetGuidFromLowGuid(TYPE_PLAYER, UID);
}
inline ObjGUID GetGuid4Gs(ObjGUID objGuid) {
	return objGuid.SID = 0, objGuid;
}
inline ObjGUID MakeGuid(uint16 SID, uint16 TID, uint32 UID) {
	ObjGUID objGuid;
	objGuid.SID = SID;
	objGuid.TID = TID;
	objGuid.UID = UID;
	return objGuid;
}

inline InstGUID GetInstGuidFromValue(uint64 instGUID) {
	InstGUID instGuid;
	instGuid.instGUID = instGUID;
	return instGuid;
}
inline InstGUID MakeInstGuid(uint16 TID, uint16 MAPID, uint32 UID = INST_UID_INVALID) {
	InstGUID instGuid;
	instGuid.TID = TID;
	instGuid.MAPID = MAPID;
	instGuid.UID = UID;
	return instGuid;
}

inline INetStream& operator<<(INetStream& pck, const ObjGUID& arg) {
	return pck << arg.objGUID;
}
inline INetStream& operator>>(INetStream& pck, ObjGUID& arg) {
	return pck >> arg.objGUID;
}
inline INetStream& operator<<(INetStream& pck, const InstGUID& arg) {
	return pck << arg.instGUID;
}
inline INetStream& operator>>(INetStream& pck, InstGUID& arg) {
	return pck >> arg.instGUID;
}

extern const vector3f vector3f_INVALID;
extern const vector3f vector3f_NULL;
extern const vector3f1f vector3f1f_NULL;
extern const vector3f3f vector3f3f_NULL;

inline INetStream& operator<<(INetStream& pck, const vector3f& arg) {
	return pck << arg.x << arg.y << arg.z;
}
inline INetStream& operator>>(INetStream& pck, vector3f& arg) {
	return pck >> arg.x >> arg.y >> arg.z;
}
inline INetStream& operator<<(INetStream& pck, const vector3f1f& arg) {
	return pck << arg.x << arg.y << arg.z << arg.o;
}
inline INetStream& operator>>(INetStream& pck, vector3f1f& arg) {
	return pck >> arg.x >> arg.y >> arg.z >> arg.o;
}
inline INetStream& operator<<(INetStream& pck, const vector3f3f& arg) {
	return pck << arg.x << arg.y << arg.z << arg.ox << arg.oy << arg.oz;
}
inline INetStream& operator>>(INetStream& pck, vector3f3f& arg) {
	return pck >> arg.x >> arg.y >> arg.z >> arg.ox >> arg.oy >> arg.oz;
}

inline vector3f vector3f_normalize_2d(vector3f arg) {
	return arg.y = 0, arg.normalize(), arg;
}
inline vector3f vector3f_normalize(vector3f arg) {
	return arg.normalize(), arg;
}
inline vector3f vector3f_rotateXZBy(vector3f arg, float angle) {
	return arg.rotateXZBy(angle), arg;
}
